# @Author     ：SEED
# @DateTime   ：2019-09-24  19:13 
# @FileName   ：deploy.py

from deployment.models import DeployOrder
import os, time
import json
from django.core.exceptions import ObjectDoesNotExist
from deployment.serializers.deploy_serializer import DeployOrderSerializer, DeployOrderSerializerDepth, \
    BuildRecordSerializer
from rest_framework import viewsets
from common.custom import CustomPagination, RbacPermission
from rest_framework.views import APIView
from utils.git_tools import GitTools
from utils.websocket_tail import Tailf
from utils.fabric import Shell
from ..models import Project, BuildRecord, DeployRecord
import subprocess
from HzrsOps2 import settings
from rest_framework import status as json_status
from common.custom import MyResponse
from common.custom_filter import BuildRecordFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.response import Response
from ..tasks import Deploy, deploy


class BuildRecordView(APIView):
    # authentication_classes = (JSONWebTokenAuthentication,)
    @staticmethod
    def get(request):
        order_id = request.query_params['deploy_order_id']
        output = {}
        a = BuildRecord.objects.get(deploy_order_id=order_id)
        b = a.output.lstrip('[').rstrip(']')
        output = eval(b)
        data = {
            'status': a.status,
            'output': output,
            'start_time': a.start_time,
            'end_time': a.end_time,
            'errmsg': a.errmsg,
        }
        return MyResponse(data, status=json_status.HTTP_200_OK)


class DeployRecordView(APIView):
    # authentication_classes = (JSONWebTokenAuthentication,)

    def get(self, request):
        order_id = request.query_params['deploy_order_id']
        output = {}
        a = DeployRecord.objects.get(deploy_order_id=order_id)
        b = a.output.lstrip('[').rstrip(']')
        output = eval(b)
        data = {
            'status': a.status,
            'output': output,
            'start_time': a.start_time,
            'end_time': a.end_time,
            'errmsg': a.errmsg,
        }
        return MyResponse(data, status=json_status.HTTP_200_OK)


class DeployOrderViewSet(viewsets.ModelViewSet):
    """
    上线单
    """
    perms_map = (
        {'*': 'admin'}, {'*': 'project_all'}, {'get': 'project_list'}, {'post': 'project_create'},
        {'put': 'project_edit'},
        {'delete': 'project_delete'})
    queryset = DeployOrder.objects.all()
    serializer_class = DeployOrderSerializer
    pagination_class = CustomPagination
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    search_fields = ('name',)

    # authentication_classes = (JSONWebTokenAuthentication,)
    # permission_classes = (RbacPermission,)

    def get_serializer_class(self):
        # 根据请求类型动态变更serializer
        if self.action == 'list':
            return DeployOrderSerializerDepth
        return DeployOrderSerializer


class VersionView(APIView):
    authentication_classes = (JSONWebTokenAuthentication,)
    _path = settings.WORKSPACE

    def get(self, request):
        method = request.query_params['method']
        order_id = request.query_params['order_id']
        path = self._path.rstrip('/') + '/' + str(order_id)
        if method == 'branch':
            result = GitTools.branch(path)
            return MyResponse(filter(None, result))
        elif method == 'commit':
            branch = request.query_params['branch']
            result = GitTools.log(path=path, branch=branch)
            return MyResponse(filter(None, result))
        else:
            result = GitTools.tag(path)
            return MyResponse(filter(None, result))


class BuildStartView(APIView):
    @staticmethod
    def post(request):
        order_id = request.query_params['deploy_order_id']
        start_time = str(int(time.time()))
        a = BuildRecord.objects.filter(deploy_order_id=order_id)
        if a:
            BuildRecord.objects.filter(deploy_order_id=order_id).update(status='正在构建', start_time=start_time)
        else:
            BuildRecord.objects.update_or_create(deploy_order_id=order_id, status='正在构建', start_time=start_time)
        return MyResponse('success', json_status.HTTP_200_OK)


class DeployStartView(APIView):
    def post(self, request):
        order_id = request.query_params['order_id']
        project_id = request.query_params['project_id']
        order_name = request.query_params['order_name']
        web_user = request.user.username
        start_time = str(int(time.time()))
        record_id = str(order_name) + '_' + str(start_time)
        DeployRecord.objects.create(status='Failed', deploy_order_id=order_id, start_time=start_time)
        DeployOrder.objects.filter(id=order_id).update(status='Failed')
        DO = DeployOrder.objects.get(id=order_id)
        server_tag_id = DO.project.server_tags
        # Project.objeßcts.filter(id=id).update(last_task_status='Failed')
        # local_log_path = self._path.rstrip('/') + '/' + str(id) + '_' + str(request.data['alias']) + '/logs'
        # log = local_log_path + '/' + record_id + '.log'
        # version = request.data['version'].strip()
        # serverid = request.data['server_ids']
        # # 调用celery异步任务
        deploy.delay(start_time, order_id)
        # deploy.run(id, log, version, serverid, record_id, webuser, self.start_time)
        return MyResponse(record_id)


class BuildView(APIView):
    authentication_classes = (JSONWebTokenAuthentication,)
    _path = settings.WORKSPACE

    def post(self, request):
        """
        项目初始化
        :param request: post
        :return: response
        """
        project_id = request.query_params['project_id']
        order_id = request.query_params['order_id']
        repo = Project.objects.filter(id=int(project_id)).values('repo_url')
        path = self._path.rstrip('/') + '/' + order_id + '/'
        if not os.path.exists(path): os.makedirs(path)
        local = Shell('127.0.0.1')
        output = []
        command = 'rm -rf {path}'.format(path=path)
        with local.cd(path):
            result = local.local(command, webuser='admin')
            cmd = {'cmd': result.command, 'stdout': result.stdout, 'stderr': result.stderr, 'status': result.exited}
            output.append(cmd)
        if result.exited == 0:
            command = 'git clone {repo_url} {path}'.format(path=path, repo_url=repo[0]['repo_url'])
            result = local.local(command, webuser='admin')
            cmd = {'cmd': result.command, 'stdout': result.stdout, 'stderr': result.stderr, 'status': result.exited}
            output.append(cmd)
            if result.exited == 0:
                DeployOrder.objects.filter(id=order_id).update(init_status='初始化成功')
                return MyResponse('初始化成功 生成的临时目录位置:' + path, json_status.HTTP_200_OK)
            else:
                DeployOrder.objects.filter(id=order_id).update(init_status='初始化失败')
            local.close()
            return MyResponse(result.stderr, status=json_status.HTTP_400_BAD_REQUEST)
        else:
            DeployOrder.objects.filter(id=order_id).update(init_status='初始化失败')
            local.close()
        return MyResponse(result.stderr, status=json_status.HTTP_400_BAD_REQUEST)
